<?php
/**
 * User authentication session storage and API
 *
 * @link http://webappkit.net
 * @package webappkit
 * @subpackage engine
 * @author J.Ducastel <nospam0@ducastel.name>
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * @property DbLinkTool $link
 */
class UserAuthSessions /*extends DbCollection*/ {

    /**
     * @param DbLinkTool $link
     */
    public function __construct(&$link) {
        $this->link = $link;
    }

    /**
     * create a user auth session, save it into DB, then return it
     * @param mixed $user_id
     * @param int $duration session duration in hours, default is 14 days
     * @param bool $set_cookie if true, will set a cookie with default values
     * @return UserAuthSession
     */
    public function create($user_id, $duration=336, $set_cookie=false) {
        $session = UserAuthSession::factory($user_id, $duration);
        $sql = $this->_sqlReplace($session);
        $result = $this->link->getResult($sql);
        if ($result->failed())
            return false;
        return $session;
    }

    /**
     * get a session from DB
     * @param string $id session id
     * @return UserAuthSession|false
     */
    public function get($id) {
        $sql = "SELECT * FROM user_auth_sessions WHERE id='$id'";
        $result = $this->link->getResult($sql);
        return $this->_sessionFromResult($result);
    }

    /**
     * sets cookie  with session id
     * @param UserAuthSession $session
     * @return bool
     */
    public function setCookie($session, $name='auth_session') {
        $value = $session->id;
        $expires = $session->end_date->toTimestamp();
        $path = '/';
        // return setcookie($name, $value, $expires, $path, $domain);
    }

    /**
     * search for cookie, if found will search and return session from DB
     * @param string $name cookie name default to auth_session
     * @return UserAuthSession
     */
    public function getCurrent($name='auth_session') {
        if (!isset($_COOKIE[$name]))
            return false;
        return $this->get($_COOKIE[$name]);
    }

    /**
     * close session
     * sets expiration date to now, save session, then delete cookie
     * @param UserAuthSession $session
     * @return bool
     */
    public function close(&$session) {
        $session->close(); // echo '<pre>'; print_r($session);
        return $this->update($session);
    }

    /**
     * save session
     * @param UserAuthSession $session
     * @return bool
     */
    public function update($session) {
        $sql = $this->_sqlReplace($session);
        $result = $this->link->getResult($sql); // print_r($result);
        return !$result->failed();
    }

    /**
     * create table
     * @return bool
     */
    public function install() {
        $sql = 'CREATE TABLE IF NOT EXISTS user_auth_sessions(
        id char(32) primary key not null
        , token varchar(32) not null
        , user_id varchar(32) not null
        , start_date datetime not null
        , end_date datetime not null);';
        $result = $this->link->getResult($sql);
        return !$result->failed();
    }

    /**
     * get sql insertion query
     * @param UserAuthSession $session
     * @return string
     * /
    protected function _sqlInsert($session) {
        return 'INSERT INTO user_auth_sessions SET '
        ."id = '{$session->id}'"
        .", token = '{$session->token}'"
        .", user_id = '{$session->user_id}'"
        .", start_date = '".$session->start_date->toMysqlDatetime()."'"
        .", end_date = '".$session->end_date->toMysqlDateTime()."'";
    }/**/

    /**
     * get sql update query
     * @param UserAuthSession $session
     * @return string
     */
    protected function _sqlReplace($session) {
        return 'REPLACE INTO user_auth_sessions SET '
        ."id = '{$session->id}'"
        .", token = '{$session->token}'"
        .", user_id = '{$session->user_id}'"
        .", start_date = '".$session->start_date->toMysqlDatetime()."'"
        .", end_date = '".$session->end_date->toMysqlDateTime()."'";
    }

    /**
     * @param DbResult $result
     * @return UserAuthSession
     */
    protected function _sessionFromResult($result) {
        if (!$data = $result->fetchAssoc())
            return false;
        return new UserAuthSession($data);
    }
}